package com.cowealth.platform.common.base.adapter;

import com.google.gson.TypeAdapter;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 自定义Object类型的gson解析适配器，参考
 * @see com.google.gson.internal.bind.ObjectTypeAdapter
 * 对NUMBER类型做特殊处理
 *
 * @author : skycdm
 * @version : 1.0.0
 * @date : 2020/7/1 15:02
 */
public class CustomObjectTypeAdapter extends TypeAdapter<Object> {


    @Override
    public void write(JsonWriter jsonWriter, Object o) throws IOException {

    }

    @Override
    public Object read(JsonReader jsonReader) throws IOException {
        JsonToken token = jsonReader.peek();
        switch (token) {
            case BEGIN_ARRAY:
                List<Object> list = new ArrayList<Object>();
                jsonReader.beginArray();
                while (jsonReader.hasNext()) {
                    list.add(read(jsonReader));
                }
                jsonReader.endArray();
                return list;
            case BEGIN_OBJECT:
                Map<String, Object> map = new LinkedTreeMap<String, Object>();
                jsonReader.beginObject();
                while (jsonReader.hasNext()) {
                    map.put(jsonReader.nextName(), read(jsonReader));
                }
                jsonReader.endObject();
                return map;
            case STRING:
                return jsonReader.nextString();
            case NUMBER:
                //改写数字的处理逻辑，将数字值分为整型与浮点型。不然都将处理为Double,，如将200处理为200.0
                double dbNum = jsonReader.nextDouble();
                // 数字超过long的最大值，返回浮点类型
                if (dbNum > Long.MAX_VALUE) {
                    return dbNum;
                }
                // 判断数字是否为整数值
                long lngNum = (long) dbNum;
                if (dbNum == lngNum) {
                    return lngNum;
                } else {
                    return dbNum;
                }
            case BOOLEAN:
                return jsonReader.nextBoolean();
            case NULL:
                jsonReader.nextNull();
                return null;
            default:
                throw new IllegalStateException();
        }
    }
}
